#ifndef _CRT_QQUEUE_H_
#define _CRT_QQUEUE_H_

#include <stddef.h>

typedef void *_QUEUE[2];

#define _QUEUE_NEXT(q)       (*(_QUEUE **) &((*(q))[0]))
#define _QUEUE_PREV(q)       (*(_QUEUE **) &((*(q))[1]))
#define _QUEUE_PREV_NEXT(q)  (_QUEUE_NEXT(_QUEUE_PREV(q)))
#define _QUEUE_NEXT_PREV(q)  (_QUEUE_PREV(_QUEUE_NEXT(q)))

#define _QUEUE_DATA(ptr, type, field)											\
  ((type *) ((char *) (ptr) - offsetof(type, field)))


#define _QUEUE_FOREACH(q, h)													\
  for ((q) = _QUEUE_NEXT(h); (q) != (h); (q) = _QUEUE_NEXT(q))

#define _QUEUE_EMPTY(q)															\
  ((const _QUEUE *) (q) == (const _QUEUE *) _QUEUE_NEXT(q))

#define _QUEUE_HEAD(q)															\
  (_QUEUE_NEXT(q))

#define _QUEUE_INIT(q)															\
  do {																			\
    _QUEUE_NEXT(q) = (q);														\
    _QUEUE_PREV(q) = (q);														\
  }																				\
  while (0)

#define _QUEUE_ADD(h, n)														\
  do {																			\
    _QUEUE_PREV_NEXT(h) = _QUEUE_NEXT(n);                                       \
    _QUEUE_NEXT_PREV(n) = _QUEUE_PREV(h);                                       \
    _QUEUE_PREV(h) = _QUEUE_PREV(n);                                            \
    _QUEUE_PREV_NEXT(h) = (h);													\
  }																				\
  while (0)

#define _QUEUE_SPLIT(h, q, n)													\
  do {																			\
    _QUEUE_PREV(n) = _QUEUE_PREV(h);                                            \
    _QUEUE_PREV_NEXT(n) = (n);													\
    _QUEUE_NEXT(n) = (q);														\
    _QUEUE_PREV(h) = _QUEUE_PREV(q);                                            \
    _QUEUE_PREV_NEXT(h) = (h);													\
    _QUEUE_PREV(q) = (n);														\
  }																				\
  while (0)

#define _QUEUE_MOVE(h, n)														\
  do {																			\
    if (_QUEUE_EMPTY(h))														\
      _QUEUE_INIT(n);															\
    else {																		\
      _QUEUE* q = _QUEUE_HEAD(h);                                               \
      _QUEUE_SPLIT(h, q, n);													\
    }																			\
  }																				\
  while (0)

#define _QUEUE_INSERT_HEAD(h, q)												\
  do {																			\
    _QUEUE_NEXT(q) = _QUEUE_NEXT(h);                                            \
    _QUEUE_PREV(q) = (h);														\
    _QUEUE_NEXT_PREV(q) = (q);													\
    _QUEUE_NEXT(h) = (q);														\
  }																				\
  while (0)

#define _QUEUE_INSERT_TAIL(h, q)												\
  do {																			\
    _QUEUE_NEXT(q) = (h);														\
    _QUEUE_PREV(q) = _QUEUE_PREV(h);                                            \
    _QUEUE_PREV_NEXT(q) = (q);													\
    _QUEUE_PREV(h) = (q);														\
  }																				\
  while (0)

#define _QUEUE_REMOVE(q)														\
  do {																			\
    _QUEUE_PREV_NEXT(q) = _QUEUE_NEXT(q);                                       \
    _QUEUE_NEXT_PREV(q) = _QUEUE_PREV(q);                                       \
  }																				\
  while (0)

#endif
